/**
 * phi
 */

var extend = function(dest, source) {
    for (var property in source) {
        dest[property] = source[property];
    }
    return dest;
};


/**
 * クラス生成
 * superClass があった場合は継承する
 * @param {Object} prop
 */
var createClass = function(prop) {
    var DEFAULT = {
        init: function() {},
        superClass: null,
    };
    
    var data = extend(DEFAULT, prop);
    
    var temp_class = function(){
        var temp = new temp_class.prototype.creator();
        
        // if (temp.superInit) {
            // temp.superInit.apply(temp, arguments);
        // }
        temp_class.prototype.init.apply(temp, arguments);
        
        return temp;
    }
    
    if (data.superClass) {
        // 
        temp_class.prototype = data.superClass.prototype;
        // TM.extend(temp_class.prototype, data.superClass.prototype);
        temp_class.prototype.superInit = data.superClass.prototype.init;
    }
    
    // メソッド登録
    extend(temp_class.prototype, data);
    // クリエイタの生成 & 継承
    temp_class.prototype.creator = function() { return this; }
    temp_class.prototype.creator.prototype = temp_class.prototype;
    
    return temp_class;
};




/**
 * Element
 */
var Element = createClass({
    parent: null,
    
    init: function() {}
});



/**
 * ElementContainer
 */
var ElementContainer = createClass({
    superClass: Element,
    init: function()
    {
        this.superInit();
        this.children = [];
    },
    
    exec: function(func_name)
    {
        var args = Array.prototype.slice.apply(arguments);
        args.splice(0, 1);
        
        for (var i=0; i<this.children.length; ++i) {
            var child = this.children[i];
            child[func_name].apply(child, args);
            // 関数内で remove が呼ばれていた場合の調整
            if (child != this.children[i]) --i;
        }
    },
    
    appendChild: function(child)
    {
        child.parent= this;
        this.children.push(child);
        
        return child;
    },
    
    removeChild: function(child)
    {
        var index = this.children.indexOf(child);
        if (index != -1) this.children.splice(index, 1);
    }
});










